package ift585.tp2;

import java.io.IOException;
import java.net.*;
import java.util.*;
import java.util.concurrent.Semaphore;

public class RouterSender implements Runnable{
	private static final int PORT_OFFSET = 1;
	private static final int ADDRESS_OFFSET = 0;
	private static final String ADDRESS_PORT_SPLITTER = ":";
	private boolean doitTravailler = true;
	private Semaphore messageToSendEvent = new Semaphore(0);
	private Semaphore mutex = new Semaphore(1);
	private DatagramSocket sendingSocket = null;
	
	private List<Message> messageToSend = new ArrayList<Message>();
	private int sendingPort;
	
	public RouterSender(int SendingPort) throws SocketException{
		sendingPort = SendingPort;
		sendingSocket = new DatagramSocket();
	}
	
	@Override
	public void run() {
		while(doitTravailler){
			try {
				messageToSendEvent.acquire();
				mutex.acquire();
				if(! messageToSend.isEmpty()){
					sendMessagesBatch();
				}
				mutex.release();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	private void sendMessagesBatch() throws InterruptedException, IOException {
		for(int i=0 ; i < messageToSend.size() ; ++i){
			byte [] dataToSend = MessageUtility.serializeMessage(messageToSend.get(i));
			
			String [] addressAndPort = messageToSend.get(i).getNextHop().split(ADDRESS_PORT_SPLITTER);
			
			sendingSocket.send(new DatagramPacket(dataToSend, dataToSend.length, InetAddress.getByName(addressAndPort[ADDRESS_OFFSET]), Integer.valueOf(addressAndPort[PORT_OFFSET])));
		}
		messageToSend.clear();
	}


	public void stopWorking() throws InterruptedException{
		messageToSendEvent.acquire();
		doitTravailler=false;
	}

	public void addWork(Message receivedMessage) throws InterruptedException {
		mutex.acquire();
		messageToSend.add(receivedMessage);
		mutex.release();
		messageToSendEvent.release();
	}
}
